import { BaseResp, BaseError } from "../../entity/BaseEntity";
import { IGlobal } from "../../entity/Global";
import { EnumCode } from "../../entity/Code";
import { PlusRedis } from "../PlusRedis";

declare var global: IGlobal;
export class BaseService {
    private _methodList: RegistMethodVo[];
    constructor() {
        this._methodList = [];
    }


    protected _regist(func: Function, method: string, uri?: string, selfResp?: boolean) {
        var str = func.toString().split("\r\n")[0];
        var arr;
        if (str.indexOf("(") != -1 && str.indexOf(")") != -1) {
            str = str.split("(")[1].split(")")[0];
            str = str.replace(/\s+/g, "");
            arr = str.split(",");
            for (var i = 0; i < arr.length; i++) {
                var dengIndex = arr[i].indexOf("=");
                if (dengIndex != -1) {
                    arr[i] = String(arr[i]).substring(0, dengIndex);
                }
            }
        }
        let methodVo = new RegistMethodVo(this, func, func.name, method, ...arr);
        methodVo.uri = uri;
        methodVo.selfResp = !!selfResp;
        this._methodList.push(methodVo);
    }

    throwError(message: string, code?: number) {
        throw new BaseError(message, code);
    }


    public get methods() {
        return this._methodList;
    }

    public get log() {
        return global.log;
    }

    get redis() {
        return global.plus.getPlus(PlusRedis).client;
    }
}


export class RegistMethodVo {
    public func: Function;
    public name: string;
    public args: Array<any>;
    public caller: any;
    public method: string;
    public uri: string;
    public selfResp: boolean;
    constructor(caller: any, func: Function, name: string, method: string, ...args) {
        this.func = func;
        this.name = name;
        this.args = args;
        this.caller = caller;
        this.method = method;
    }

    execute = async (ctx) => {
        var arg = [];
        var data = this.method == "post" ? ctx.request.body : ctx.request.query;
        for (var i = 0; data && this.args && i < this.args.length; i++) {
            arg.push(data[this.args[i]]);
        }
        arg.push(ctx);
        try {
            let time = Date.now();
            var result = await this.func.call(this.caller, ...arg);
            if(this.selfResp) {
                ctx.body = result;
            }
            else {
                ctx.body = new BaseResp(200, result);
            }
            global.log.trace("[" + this.name + "]耗时" + (Date.now() - time) + "ms");
        } catch (err) {
            global.log.error("失败" + this.name + "----" + (data ? JSON.stringify(data) : "") + "\r\n" + err.stack);
            ctx.body = new BaseResp(err.code || EnumCode.FAIL, err.message);
        }
    }
}